using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Deepcode.Flux.Core.Data;
using Deepcode.Flux.Core.Services.Configuration;
using Deepcode.Flux.Core.Systems.Workflow.Bases;
using Deepcode.Flux.Core.Systems.Workflow.Enums;
using Deepcode.Flux.Core.Systems.Workflow.Info;
using Deepcode.Flux.Core.Systems.Workflow;
using Deepcode.Flux.Core.Services.State;
using Deepcode.Flux.Core.Extensions;
using Deepcode.Flux.Core.Systems.Audit.Quick;
using Deepcode.Flux.Core.Services.Assistant;

public partial class Private_Config_Workflow_ui_exitpath : Deepcode.Flux.Core.UI.AdministrationModulePage
{
	#region Permission Code Override
	public override string RequiredPermissionCode { get { return "FluxWorkflowEdit"; } }
	#endregion
	#region ViewState storage
	/// <summary>
	/// Stores the ID of the handler which this form
	/// is adding a new definition to.
	/// </summary>
	public string HandlerID
	{
		get
		{
			object o = ViewState["HandlerID"];
			if (o == null) return String.Empty;
			return (string)o;
		}
		set
		{
			ViewState["HandlerID"] = value;
		}
	}
	/// <summary>
	/// Stores the ID of the definition being edited
	/// </summary>
	public int DefinitionID
	{
		get
		{
			object o = ViewState["DefinitionID"];
			if (o == null) return -1;
			return (int)o;
		}
		set
		{
			ViewState["DefinitionID"] = value;
		}
	}
	/// <summary>
	/// Stores the ID of the process being edited
	/// </summary>
	public int ProcessID
	{
		get
		{
			object o = ViewState["ProcessID"];
			if (o == null) return -1;
			return (int)o;
		}
		set
		{
			ViewState["ProcessID"] = value;
		}
	}
	/// <summary>
	/// Stores the ID of the tasking being edited
	/// </summary>
	public int TaskingID
	{
		get
		{
			object o = ViewState["TaskingID"];
			if (o == null) return -1;
			return (int)o;
		}
		set
		{
			ViewState["TaskingID"] = value;
		}
	}
	/// <summary>
	/// Stores the ID of the exit path being edited
	/// </summary>
	public int TaskExitPathID
	{
		get
		{
			object o = ViewState["TaskExitPathID"];
			if (o == null) return -1;
			return (int)o;
		}
		set
		{
			ViewState["TaskExitPathID"] = value;
		}
	}
	#endregion
	#region Page Load Event
	/// <summary>
	/// Page Load event
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Load(object sender, EventArgs e)
	{
		if (!Page.IsPostBack)
		{
			// Store any state information from the calling listing
			this.HandlerID = GetAttribute("HandlerID", "");
			this.DefinitionID = GetAttribute("DefinitionID", -1);
			this.ProcessID = GetAttribute("ProcessID", -1);
			this.TaskingID = GetAttribute("TaskingID", -1);
			this.TaskExitPathID = GetAttribute("TaskExitPathID", -1);

			// Load info 
			Handler h = new Handlers().GetHandlerByID( this.HandlerID );
			if( h == null ) GoBack();
			Definition d = new Definitions().GetByID( this.DefinitionID );
			if( d == null ) GoBack();
			Process p = new Processes().GetProcessByID( this.ProcessID );
			if( p == null ) GoBack();
			Tasking t = new Taskings().GetTaskingByID( this.TaskingID );
			if( t == null ) GoBack();
			TaskExitPath tep = new TaskExitPaths().GetTaskExitPathByID( this.TaskExitPathID );
			if( tep == null ) GoBack();
			
			// Display infos
			labHandler.Text = h.Name;
			labDefinition.Text = d.DefName;
			labProcess.Text = p.ProcessName;
			labTasking.Text = t.TaskCaption;
			labExitPath.Text = tep.Caption;

			// Create an engine
			WorkflowEngine Engine = new WorkflowEngine(this.HandlerID);
			
			// Populate list of UI Methods available
			uiTaskMethod.Items.Clear();
			ListItem emptyItem = new ListItem( "(none)", "" );
			if( tep.uiTaskMethod == "" ) emptyItem.Selected = true;
			uiTaskMethod.Items.Add( emptyItem );

			foreach (WorkflowUIMethodInfo ui in Engine.GetWorkflowUIMethods())
			{
				ListItem i = new ListItem(ui.FriendlyName, ui.MethodName);
				if (tep.uiTaskMethod == ui.MethodName) i.Selected = true;
				uiTaskMethod.Items.Add(i);
			}

			// Populate list of groups available
			ArrayList SelectedGroups = new ArrayList(tep.CSV_AllowedGroups.Split(','));

			CSV_AllowedGroups.Items.Clear();
			foreach( WorkflowTaskableGroup grp in Engine.GetTaskableGroups() )
			{
				ListItem i = new ListItem( grp.GroupName, grp.GroupID.ToString() );
				if( SelectedGroups.Contains( grp.GroupID.ToString() )) i.Selected = true;
				CSV_AllowedGroups.Items.Add(i);
			}

			Caption.Text = tep.Caption;
			BindAvailableActions();
			BindActions();
		}
	}
	#endregion
	#region Initialisation
	/// <summary>
	/// Capture events etc for grids 
	/// </summary>
	protected void Page_Init()
	{
		actions.ItemDataBound += new DataGridItemEventHandler(actions_ItemDataBound);
		actions.ItemCommand += new DataGridCommandEventHandler(actions_ItemCommand);
	}
	#endregion
	#region Navigation
	/// <summary>
	/// Returns to process editor
	/// </summary>
	protected void GoBack()
	{
		string url = String.Format(
			"ui_usertask.aspx?HandlerID={0}&DefinitionID={1}&ProcessID={2}&TaskingID={3}",
			this.HandlerID,
			this.DefinitionID,
			this.ProcessID,
			this.TaskingID);
		
		Response.Redirect(url, true);
	}
	#endregion
	#region Save/Cancel handlers
	/// <summary>
	/// User cancelled the save, go back to previous page
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnCancel_Click(object sender, EventArgs e)
	{
		GoBack();
	}
	/// <summary>
	/// User clicked the save button, store the data
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnSave_Click(object sender, EventArgs e)
	{
		if (!Page.IsValid) return;

		TaskExitPaths teps = new TaskExitPaths();
		TaskExitPath t = teps.GetTaskExitPathByID( this.TaskExitPathID );
		t.Caption = this.Caption.Text;
		t.uiTaskMethod = this.uiTaskMethod.SelectedValue;
		t.CSV_AllowedGroups = ControlUtil.GetListSelectedCSV(CSV_AllowedGroups.Items);

		teps.Save( t );

		Tasking pt = t.ParentTasking;
		Process pp = pt.ParentProcess;

		QuickAudit.RaiseInformation(
			new AuditUser(),
			"Flux", "Workflow Manager",
			"modified exit path ({0}) for tasking ({1}) in process ({2})",
			t.Caption,
			pt.TaskCaption,
			pp.ProcessName);
	}
	#endregion
	#region Actions Grid
	/// <summary>
	/// Associates all of the available actions for this handler with the 
	/// available actions drop down list in startup actions
	/// </summary>
	protected void BindAvailableActions()
	{
		WorkflowEngine e = new WorkflowEngine(HandlerID);
		if (e == null) return;

		ddlActions.Items.Clear();

		foreach (WorkflowMethodInfo winfo in e.GetWorkflowMethods())
		{
			string details = String.Format("{0} ({1})", winfo.FriendlyName, winfo.MethodName);
			ddlActions.Items.Add(new ListItem(details, winfo.MethodName));
		}
	}
	/// <summary> 
	/// Bind the actions for this system tasking's only exit path
	/// </summary>
	protected void BindActions()
	{
		this.actions.BindJavascript("btnDelete", "onclick", "return ConfirmDeleteAction();");

		ExitActions eas = new ExitActions();
		this.actions.DataSource = eas.GetExitActionsForExitPathID( this.TaskExitPathID );
		this.actions.DataBind();
	}
	/// <summary>
	/// Respond to an item being bound to the grid.
	/// This will show/hide the properties button for methods
	/// that do or do not have a properties form
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	void actions_ItemDataBound(object sender, DataGridItemEventArgs e)
	{
		if ((e.Item.ItemType == ListItemType.Item) ||
			(e.Item.ItemType == ListItemType.AlternatingItem) ||
			(e.Item.ItemType == ListItemType.SelectedItem))
		{
			WorkflowEngine Engine = new WorkflowEngine(HandlerID);
			ExitAction item = (ExitAction)e.Item.DataItem;
			WorkflowMethodInfo iteminfo = Engine.GetWorkflowMethodInfo(item.Method);
			if (iteminfo == null) return;
			// Determine if the properties link should appear
			if (!iteminfo.HasConfig)
			{
				LinkButton btn = (LinkButton)e.Item.FindControl("btnProperties");
				if (btn != null) btn.Visible = false;
			}
		}
	}
	/// <summary>
	/// Action being added to the exit path
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void btnAddAction_Click(object sender, EventArgs e)
	{
		TaskExitPath tep = new TaskExitPaths().GetTaskExitPathByID( this.TaskExitPathID );
		tep.AddAction( this.ddlActions.SelectedValue );

		QuickAudit.RaiseInformation(
			new AuditUser(),
			"Flux", "Workflow Manager",
			"added action ({0}) to exit path ({1}) for tasking ({2})",
			this.ddlActions.SelectedValue,
			tep.Caption,
			tep.ParentTasking.TaskCaption);

		this.BindActions();
	}
	/// <summary>
	/// User has invoked an option on one of the associated actions
	/// </summary>
	/// <param name="source"></param>
	/// <param name="e"></param>
	void actions_ItemCommand(object source, DataGridCommandEventArgs e)
	{
		if (e.Item.ItemType == ListItemType.Footer ||
			e.Item.ItemType == ListItemType.Header ||
			e.Item.ItemType == ListItemType.Pager ||
			e.Item.ItemType == ListItemType.Separator) return;

		// Get the key of the row being actioned 
		int rowKey = (int)actions.DataKeys[e.Item.ItemIndex];

		// PROCESS COMMANDS
		if (e.CommandName == "ItemDelete")
		{
			ExitActions eas = new ExitActions();
			ExitAction ea = eas.GetExitActionsByID(rowKey);
			if (ea == null) return;

			eas.DeleteByID(rowKey);
			BindActions();

			QuickAudit.RaiseInformation(
				new AuditUser(),
				"Flux", "Workflow Manager",
				"deleted action ({0}) from exit path ({1}) in tasking ({2})",
				ea.Method,
				ea.ParentExitPath.Caption,
				ea.ParentExitPath.ParentTasking.TaskCaption);
		}

		if (e.CommandName == "ItemUp")
		{
			ExitActions eas = new ExitActions();
			eas.ShuffleUp(rowKey);
			this.BindActions();
		}

		if (e.CommandName == "ItemDown")
		{
			ExitActions eas = new ExitActions();
			eas.ShuffleDown(rowKey);
			this.BindActions();
		}

		if (e.CommandName == "ItemProperties")
		{
			string url = String.Format(
				"ui_actionprop.aspx?HandlerID={0}&DefinitionID={1}&ProcessID={2}&TaskingID={3}&TaskExitPathID={4}&ExitActionID={5}",
				this.HandlerID,
				this.DefinitionID,
				this.ProcessID,
				this.TaskingID,
				this.TaskExitPathID,
				rowKey);

			Response.Redirect(url, true);
		}
	}
	#endregion
}
